# -*- coding: UTF-8 -*-
__author__ = 'kennyh'
from twisted.internet.protocol import Factory
from twisted.internet import threads
from server_protocol import *
from Queue import Queue
import threading
import binascii
import random
import traceback
import string
import copy
from pack import *
from unpack import *
import struct
from MysqlSet import *
import json
from datetime import datetime as dt_date_time
import time

from logger import logger
from constant import CMD_TIME_INTERVAL,DECODE_DATA_INTERVAL,\
    HEART_CHECK_INTERVAL,QUERY_TIME_INTERVAL,SAVE_DATA_INTERVAL,\
    MYSQL_CHECK_INTERVAL
import sys
import global_buffer

reload(sys)
sys.setdefaultencoding('gbk')


class ServerFactory(Factory):
    protocol = ServerProtocol
    def __init__(self, storageTag):
        self.storageTag = storageTag
        self.is_result_thread_locked = False
        self.patrol_send_thread_count = 0
        self.is_send_thread_locked = False
        self.patrol_send_thread_locked = False

        self.msg_buffer = []   #received messages buffer
        self.save_db_buffer_dict = storageTag.save_db_buffer_dict #patrol result list

        self.query_result_dict = {} #send read register cmd result
        self.single_broadcast_cmd_result = {}  #single broadcast cmd result

        self.cmd_buffer = []   #control cmd buffer
        self.send_result = []   #send control cmd result

        self.clients = []
        self.msg=''

        self.debugclients = []
        self.debugtarget = ['ysx44', 'srne']

        self.proclientsdict = {}
        self.netlistdict = {}
        self.sendrecord = []
        self.pushuserlists = []
        self.mysqlDb = storageTag.mysqlDb
        # self.mysqlDb.open()
        self.mysqlDb.reset_network_status([])  #initialize network status
        self.mysqlDb.reset_update_status()  #initialize update status

        self.lamp_config_info_dict = {}
        self.read_lamp_config()
        self.patrol_sendlock = threading.RLock()

        self.send_thread_record_time = dt_date_time.now() #per 1 hour
        self.send_cmd_time = dt_date_time.now()   #per 1s
        self.heart_beat_record_time = dt_date_time.now()  #5s
        self.chek_result_record_time = dt_date_time.now()  #5s
        self.decode_thread_record_time = dt_date_time.now()  #per 1s

        self.decode_thread_record_tick = 0
        self.main_thread_tick = 0
        self.clear_result_cmd_time = 0
        self.run_mode = "release"

        file_object = open('run.conf')
        try:
            all_lines = file_object.readlines()
            for line in all_lines:
                items = line.split("=")
                if items[0].strip() == 'ENV':
                    self.run_mode = items[-1].strip()
                    break;
        finally:
            file_object.close()

        #函数主线程
        self.MainThread = threads.deferToThread(self.project_main_thread)
        self.MainThread.addCallback(self.send_data_success)

        self.decodeThread = threads.deferToThread(self.decodeDataThread)
        self.decodeThread.addCallback(self.send_data_success)

        self.data_decode = UnPackData()
        self.data_encode = PackSendData()

    def read_lamp_config(self):
        #从数据库读取配置信息，作为全局变量

        result,self.lamp_config_info_dict =self.mysqlDb.readLampInfo()
        if not result:
            result,self.lamp_config_info_dict =self.mysqlDb.readLampInfo()

    def send_query_single(self,client,address_default,pdu,type,is_complete = 0):
        senddata = ""
        try:

            address = broadcast_address
            if type == 0:
                address = address_default
            if is_complete:
                senddata = self.data_encode .EncodeQueryAllCompleteCmd(address,3,pdu,[])
            else:
                senddata = self.data_encode .EncodeCompleteCmd(address,3,pdu,[])
            #client.transport.write(senddata)
            client.transport.getHandle().sendall(senddata)
            time.sleep(0.001)
            self.print_debug_info(senddata,0)
        except Exception,e:
            self.print_debug_info(senddata,0)
            logger.error("send_query_single error %s" % str(e))

    def print_debug_info(self,senddata,type):
        pass

        try:
            send_data = ""
            for k, count in enumerate(senddata):
                hexstr = binascii.b2a_hex(count)
                send_data = "%s%s"%(send_data,hexstr)
            if type == 0:
                logger.info("senddata info %s" % send_data)
            else:
                logger.info("recvdata info %s" % send_data)
        except Exception,e:
            logger.error( "print_debug_info error: %s"% str(e))


    def print_string2hex(self,stringData, netid):
        try:
            send_data = ""
            for k, count in enumerate(stringData):
                hexstr = binascii.b2a_hex(count)
                send_data = "%s%s"%(send_data,hexstr)
            logger.info("netid %s unknown Data %s" % (netid,send_data))
        except Exception,e:
            logger.error( "print_string2hex error: %s"% str(e))

    def send_data_success(self,result):
        if type(result) == dict:
            if self.run_mode == 'debug' or self.run_mode == 'DEBUG':
                print result.get("message",'no message')
            elif result.get('result',False):
                pass
                #logger.info(result.get("message",'no message'))

    def addClient(self, newclient):
        newClientItem = {
        "client": newclient,
        'last_time': dt_date_time.now()
        }
        self.clients.append(newClientItem)

    def addProClient(self,newrelation):
        if newrelation['user_name'] in self.debugtarget:
            self.debugclients.append(newrelation)

        self.proclientsdict[newrelation['unique_id']] = newrelation

        for citem in self.clients:
            if(citem['client'] == newrelation['client']):
                self.clients.remove(citem)


    def delClient(self, client):
        try:
            ipAddr = client.getIPaddr()
            client_item, network_id = self.getClientByIPaddr(ipAddr)
            if client_item != None:
                logger.error("delete client %s network id %s name %s" % (client.getId(),network_id, client_item['user_name']))
                self.mysqlDb.reset_network_status([{'network_id':network_id,'status':0,'ip':'', 'port':''}])
                #if client_item['client'].getIPaddr() == ipAddr:
                del self.proclientsdict[network_id]
            if ipAddr in self.netlistdict:
                del self.netlistdict[ipAddr]

        except Exception, e:
            logger.error("delClient: %s" % str(e))

    def getClientByNetworkid(self, networkid):
        client_item = {}
        try:
            client_item = self.proclientsdict[networkid]
        except Exception, e:
            return {}
        return client_item

    def getClientByIPaddr(self, ipAddr):
        client_item = {}
        network_id = 0
        try:

            network_id = self.netlistdict.get(ipAddr, 0)
            client_item = self.proclientsdict.get(network_id, None)
        except Exception, e:
            return {}, 0
        return client_item, network_id

    def getQueryItemByAddress(self, address):
        query_item = {}
        try:
            query_item = self.query_result_dict[address]
        except Exception, e:
            return {}
        return query_item

    def chek_query_result_thread(self):
        '''
        检测发送结果的线程
        :return:
        '''
        self.is_result_thread_locked = True
        self.clear_result_cmd_time += 5
        current_time = dt_date_time.now()
        try:
            cmd_delete_buffer = []
            for item in self.send_result:
                client_item = item['recv_client']
                if item['result'] == 1 or item.get("type",0) != 0:
                    self.patrol_sendlock.acquire()
                    client_item['send_cmd'] = 0
                    self.proclientsdict[client_item['unique_id']] = client_item
                    self.patrol_sendlock.release()
                    cmd_delete_buffer.append(item)
                elif item['times'] >= 3 and (current_time - item['record_time']).seconds >= 5:
                    cmd_request = item['cmd_request']

                    self.patrol_sendlock.acquire()
                    client_item['send_cmd'] = 0
                    self.proclientsdict[client_item['unique_id']] = client_item
                    self.patrol_sendlock.release()
                    logger.error("patrol not response, lampid %s" % str(cmd_request['address']))
                    cmd_delete_buffer.append(item)

                elif (current_time - item['record_time']).seconds >= 5 and item['times'] < 3:
                    cmd_key = item.get("cmd_key")
                    if cmd_key in self.single_broadcast_cmd_result:
                        #如果为单播命令，则需要先确认是否所有指令都已经发送完成，如果未发送，则暂时不做重发
                        if not self.single_broadcast_cmd_result.get(cmd_key).get("is_all_query_send"):
                            continue
                    item['record_time'] = current_time
                    client_item = item['recv_client']
                    client = client_item['client']

                    cmd_request = item['cmd_request']
                    senddata = self.data_encode.EncodeCompleteCmd(cmd_request['address'], cmd_request['code'], cmd_request['pdu'], cmd_request['value'])
                    self.print_debug_info(senddata, 0)
                    client.transport.write(senddata)
                    item['times'] = item['times']+1
                    time.sleep(2)
            for item_d in cmd_delete_buffer:
                cmd_key = item.get("cmd_key")
                # 如果为单播，则重新设置单播结果
                if cmd_key in self.single_broadcast_cmd_result:
                    cur_cmd_result = self.single_broadcast_cmd_result[cmd_key]
                    cur_cmd_result['finish_nums'] = cur_cmd_result.get('finish_nums',0) + 1
                    if item_d.get("result") == 1:
                        cur_cmd_result['succeed_nums'] = cur_cmd_result.get('succeed_nums',0) + 1
                    # 如果完成量和单播发送量一致，则直接返回结果
                    if cur_cmd_result['finish_nums'] == cur_cmd_result['send_msg_num'] and cur_cmd_result.get('is_all_query_send',False):
                        return_value = json.dumps({'result': True,
                                        'msg': u'单播指令发送完成',
                                        'total_num':cur_cmd_result['send_msg_num'],
                                        'succeed_num':cur_cmd_result.get('succeed_nums',0)}) + '\n'
                        cur_cmd_result['cmd_client'].transport.write(return_value)
                        self.single_broadcast_cmd_result.pop(cmd_key)

                elif item_d['times'] >=3:
                    if 'cmd_key' not in item_d:
                        #logger.info("chek_query_result_thread::time out no response from client after 3 times request")
                        item_d['cmd_client'].transport.write(
                            json.dumps({'result': False, 'msg': 'time out no response from client after 3 times request'}) + '\n')


                self.send_result.remove(item_d)
            self.clear_result_cmd_time = 0
        except Exception, e:
            logger.error(u"check control cmd error: %s"%str(e))
        client_item = None
        try:
            query_dict_keys = self.query_result_dict.keys()
            for dictkey in query_dict_keys:
                query_item = self.getQueryItemByAddress(dictkey)
                if len(query_item) == 0:
                    continue
                client_item = self.getClientByNetworkid(query_item['networkid'])
                if len(client_item) == 0 or query_item['times'] >= 3:
                    self.patrol_sendlock.acquire()
                    client_item['send_cmd'] = 0
                    client_item['send_status'] = 0
                    self.proclientsdict[query_item['networkid']] = client_item
                    self.patrol_sendlock.release()
                    del self.query_result_dict[dictkey]
                    continue

                #waitting for concentrator return or timeout
                if client_item.has_key('send_time'):
                    last_time = client_item['send_time']
                    if client_item['send_status'] == 1 and (current_time - last_time).seconds < 5:
                        continue

                record_time = query_item['record_time']
                if (current_time - record_time).seconds >= 5:
                    query_item['record_time'] = current_time
                    if client_item.has_key('client'):
                        self.send_query_single(client_item['client'], dictkey, 0, query_item['type'], True)
                    else:
                        continue

                    if query_item.has_key('cmd_client'):
                        if query_item['respond'] == 1:
                            return_value = json.dumps({'result': True,
                                'msg': u'实时更新指令发送完成',
                                'total_num':query_item['send_num'],
                                'succeed_num':query_item['send_num']}) + '\n'
                            query_item['cmd_client'].transport.write(return_value)

                    query_item['times'] = query_item['times'] + 1
                    self.query_result_dict[dictkey] = query_item
                    self.patrol_sendlock.acquire()
                    client_item['send_status'] = 1
                    client_item['send_time'] = dt_date_time.now()
                    self.proclientsdict[query_item['networkid']] = client_item
                    self.patrol_sendlock.release()
        except Exception,e:
            logger.error("chek_query_result_thread error: %s, client_item %s" % (str(traceback.format_exc()), str(client_item)))

        self.chek_result_record_time = dt_date_time.now()
        self.is_result_thread_locked = False
        #logger.info("123chek_query_result_thread::is_result_thread_locked is {result}".format(result = self.is_result_thread_locked))
        return {'result':False,
                'message':"chek_query_result_thread : check heart beat thread end record time %s" % str(self.chek_result_record_time)}

    def chek_heart_beat_thread(self):
        '''
        监测心跳线程
        :return:
        '''
        client_item = None
        try:
            non_connect_network = []
            remove_clients = 0
            current_time = dt_date_time.now()
            for pushItem in self.pushuserlists:
                last_time = pushItem['last_time']
                if (current_time - last_time).seconds >= 60:
                    pushItem['client'].transport.loseConnection()
                    self.pushuserlists.remove(pushItem)
            net_dict_keys = self.proclientsdict.keys()
            for netdictkey in net_dict_keys:
                client_item = self.getClientByNetworkid(netdictkey)
                if len(client_item) == 0:
                    continue
                if client_item.has_key('last_time'):
                    last_time = client_item['last_time']
                    heart_period = client_item["heart_period"]
                    #if (current_time - last_time).seconds >= heart_period*3:
                    if (current_time - last_time).seconds >= 600:
                        non_connect_network.append({'network_id': client_item['unique_id'], 'status': 0,'ip':'', 'port':''})
                        remove_clients += 1
                        client_item['client'].transport.loseConnection()
                        logger.error(
                            "delete network id %s name %s， last_time %s" % (client_item['unique_id'], client_item['user_name'], last_time.strftime('%Y-%m-%d %H:%M:%S')))
                        if netdictkey in self.proclientsdict:
                            del self.proclientsdict[netdictkey]

            if remove_clients > 0:
                self.mysqlDb.reset_network_status(non_connect_network)

            for citem in self.clients:
                last_time = citem['last_time']
                if (current_time - last_time).seconds >= 120:
                    logger.error("clients(%s) not register, disconnect it"% str(citem['client'].getId()))
                    citem['client'].transport.loseConnection()
                    self.clients.remove(citem)
        except Exception, e:
            logger.error(
            "chek_query_result_thread error: %s, client_item %s" % (str(traceback.format_exc()), str(client_item)))

        self.heart_beat_record_time = dt_date_time.now()

        return {'result':False,
                'message':"chek_query_result_thread : check heart beat thread end record time %s" % str(self.heart_beat_record_time)}


    def send_cmd_request_data_thread(self):
        try:
            self.is_send_thread_locked = True
            if len(self.cmd_buffer) <= 0:
                self.is_send_thread_locked = False
                return {'result':False,
                    'message':"send_cmd_request_data_thread: thread over no cmd_buffer"
                }
            current_cmd_buffer = [msg for msg in self.cmd_buffer]
            del self.cmd_buffer[:]
            if len(current_cmd_buffer) > 0:
                self.read_lamp_config()
            for item_c in current_cmd_buffer:
                result,msg = self.send_cmd_request_single(item_c)
                if not result:
                    # 重新发一次
                    logger.error(msg)
                    result,msg = self.send_cmd_request_single(item_c)
                time.sleep(0.5)
            self.send_cmd_time = dt_date_time.now()
            self.is_send_thread_locked = False
            return {'result':True,
                'message': "send_cmd_request_data_thread:thread over record time is %s"%self.send_cmd_time}
        except:
            logger.error(traceback.format_exc())
            self.is_send_thread_locked = False

    def send_cmd_request_single(self, cmd_request):
        try:

            cmd_client = cmd_request['client']

            logger.error("cmd_request error: %s" % str(cmd_request['buffer']))
            logger.error("cmd_request error: %s" % str(cmd_request))
            result, cmd_item = UnPackData.get_json_format(cmd_request['buffer'])
            if result == False:
                return True, 'ok'

            cmd_type = cmd_item['cmd_type']
            cmd_id = cmd_item['cmd_id']

            is_broadcast = int(cmd_item.get("broadcast", 0))
            function_name = get_read_function_name(cmd_type)
            if not function_name:
                logger.error("cmd_request error: %s" % str(cmd_request))
                cmd_client.transport.write(json.dumps({'result': False, 'msg': "cmd type not existed\n"}))
                return True,'ok'
            cmd_value = []
            result = False
            if cmd_type == 'select_electric_supply':
                result, cmd_value = self.mysqlDb.select_electric_supply_cmd(cmd_item['cmdtype'], cmd_item['relateid'], cmd_item['senddata'])
            else:
                command = "result,cmd_value = self.mysqlDb.%s,%s)" % (function_name, cmd_id)
                try:
                    exec (command)
                    if not result:
                        exec (command)
                except:
                    cmd_client.transport.write(json.dumps({'result': False, 'msg': "cmd_id not existed\n"}))
                    return True, 'ok'
            if len(cmd_value) <= 0:
                cmd_client.transport.write(json.dumps({'result': False, 'msg': 'cmd not existed'}) + '\n')
            if cmd_type == 'batch_update_cmd':
                self.send_batch_update_data_new(cmd_client, cmd_value, cmd_id)
                return True, 'ok'
            for cmd in cmd_value:

                command_type = cmd['cmdtype']
                if command_type == 9:
                    udpmsg = {
                        'cmd_type': cmd_type,
                        'lampids': cmd['lampids'],
                        'actiontype': cmd['actiontype'],
                        'value': cmd['value'],
                    }
                    # logger.info("global_set_cmdmsg %s" % str(udpmsg))
                    global_buffer.global_set_cmdmsg(udpmsg)
                    return True, 'ok'
                if command_type == 10:
                    udpmsg = {
                        'cmd_type': cmd_type,
                        'cmd_client': cmd_client,
                        'protocoltype': cmd['protocoltype'],
                        'networkid': cmd['networkid'],
                        'address': cmd['address'],
                        'senddata': cmd['value'],
                    }
                    logger.info("global_set_cmdmsg %s" % str(udpmsg))
                    global_buffer.global_set_cmdmsg(udpmsg)
                    return True, 'ok'
                relateid = cmd['relateid']
                pdu = cmd['pdu']
                code = cmd['code']
                value = cmd['value']
                send_msg_num = 0
                cmd_key = "{id}_{cur_time}".format(id = cmd_id,cur_time = int(time.time()))

                if command_type == 0:
                    result, address = self.mysqlDb.get_lamp_address_info(relateid)
                    if not result:
                        result, address = self.mysqlDb.get_lamp_address_info(relateid)
                    if len(address) <= 0:
                        cmd_client.transport.write(json.dumps({'result': False, 'msg': 'relateid not existed'}) + '\n')
                        return True, 'ok'

                    int_address = address['address'] if address.has_key("address") else ''
                    networkid = address.get('networkid','')
                    net_protocoltype = address.get('protocoltype',0)
                    #logger.info(int_address)
                    #logger.info(type(int_address))
                    #logger.info(int(int_address, 16))
                    #logger.info(int(str(int_address), 16))
                    senddata = self.data_encode.EncodeCompleteCmd(int_address, code, pdu, value)

                    logger.info("relateid %d, net_protocoltype: %d, networkid %d" % (relateid, int(net_protocoltype), networkid))

                    if int(net_protocoltype) != 0:
                        '''
                        protocol type 1 would using udp to send and get data
                        '''
                        udpmsg={
                            'networkid': networkid,
                            'lampid': relateid,
                            'protocoltype': net_protocoltype,
                            'address': int_address,
                            'cmd_client': cmd_client,
                            'cmd_type': cmd_type,
                            'senddata': senddata
                        }
                        logger.info("global_set_cmdmsg %s" % str(udpmsg))
                        global_buffer.global_set_cmdmsg(udpmsg)
                        return True, 'ok'
                    else:
                        client_item = self.getClientByNetworkid(networkid)
                        if len(client_item) > 0:
                            send_msg_num += 1
                            self.patrol_sendlock.acquire()
                            client = client_item.get("client", None)
                            if client is None:
                                not_online = 'current network is not online'
                                cmd_client.transport.write(json.dumps(
                                    {'result': False, 'msg': not_online}) + '\n')
                                return True, 'ok'
                            client_item['send_cmd'] = 1
                            self.proclientsdict[networkid] = client_item
                            self.patrol_sendlock.release()
                            cmd_content = {'address':int_address,'code':code,'pdu':pdu, 'value':value}
                            self.send_result.append(
                                    {'recv_client': client_item,
                                     'cmd_client': cmd_client,
                                     'address':int_address,
                                     'result': 0,
                                     'type':0,
                                     'times':1,
                                     'pdu':pdu,
                                     'record_time':dt_date_time.now(),
                                     'cmd_request':cmd_content,
                                     'relateid':relateid
                                     })
                            #senddata = self.data_encode.EncodeCompleteCmd(int_address, code, pdu, value)
                            self.print_debug_info(senddata, 0)
                            client.transport.write(senddata)
                        else:
                            not_online = 'current network is not online'
                            logger.info("networkid %s not in line" % networkid)
                else:
                    if is_broadcast == 0:
                        # 单播命令，记录所有的发送信息
                        self.single_broadcast_cmd_result[cmd_key] = {}
                        self.single_broadcast_cmd_result[cmd_key]['cmd_client'] = cmd_client
                        self.single_broadcast_cmd_result[cmd_key]['is_all_query_send'] = False
                        self.single_broadcast_cmd_result[cmd_key]['send_msg_num'] = 0
                    if command_type == 1:
                        result, protocol_type = self.mysqlDb.get_network_protocoltype_by_id(relateid)
                        if not result:
                            result, protocol_type = self.mysqlDb.get_network_protocoltype_by_id(relateid)

                        if int(protocol_type) != 0:
                            send_msg_num += 1
                            self.udp_send_broadcast_cmd_request(cmd_type, code, pdu, value, relateid, cmd_client, cmd_key, protocol_type, is_broadcast)
                        else:
                            client_item = self.getClientByNetworkid(relateid)
                            if len(client_item) > 0:
                                send_msg_num += 1
                                self.send_broadcast_cmd_request(code, pdu, value, client_item, cmd_client, cmd_key,
                                                                is_broadcast)
                        not_online = 'current network is not online'
                    elif command_type == 2:
                        result, networkinfo = self.mysqlDb.get_networkinfo_list_by_projectid(relateid)
                        for networkitem in networkinfo:

                            protocol_type = networkitem['protocoltype']
                            if int(protocol_type) != 0:
                                send_msg_num += 1
                                self.udp_send_broadcast_cmd_request(cmd_type, code, pdu, value, networkitem['id'], cmd_client, cmd_key, protocol_type, is_broadcast)
                            else:
                                client_item = self.getClientByNetworkid(networkitem['id'])
                                if len(client_item) == 0:
                                    continue
                                if relateid == client_item['unique_prj_id']:
                                    send_msg_num += 1
                                    self.send_broadcast_cmd_request(code,pdu,value,client_item,cmd_client,cmd_key,is_broadcast)

                        not_online = 'all of networks in this project are not online'
                if send_msg_num == 0:
                    if cmd_key in self.single_broadcast_cmd_result:
                        self.single_broadcast_cmd_result.pop(cmd_key)
                    cmd_client.transport.write(json.dumps(
                            {'result': False, 'msg': not_online}) + '\n')
                elif send_msg_num != 0 and command_type != 0:
                    if is_broadcast != 0:
                        cmd_client.transport.write(json.dumps({'result': True, 'msg': '广播控制指令已经成功发送'}) + '\n')
                    elif is_broadcast == 0:
                        self.single_broadcast_cmd_result[cmd_key]['is_all_query_send'] = True
        except Exception,e:
            logger.error("send_cmd_request_single error: %s" % str(traceback.format_exc()))
            logger.error("cmd_request error: %s" % str(cmd_request))

            if cmd_client is not None:
                cmd_client.transport.write(json.dumps(
                            {'result': False, 'msg': '服务器内部错误，错误信息:{error}'.format(error= str(e))}) + '\n')
            return False,'error:%s'%str(e)
        time.sleep(2)
        return True,'ok'

    def send_broadcast_cmd_request(self, code, pdu, value, item, cmd_client,cmd_key,is_broadcast = 1):
        # 广播相关指令的发送
        client = item["client"]
        if is_broadcast == 0:
            # 单播命令先获取网络下的所有灯
            result, address_list = self.mysqlDb.get_lampinfo_groupby_network(item["unique_id"])
            if not result:
                result, address_list = self.mysqlDb.get_lampinfo_groupby_network(item["unique_id"])
            for address in address_list:
                cmd_content = {'address': address.get("address", broadcast_address),
                               'code': code,
                               'pdu': pdu,
                               'value': value}
                '''
                self.send_result.append(
                    {'recv_client': item,
                     'cmd_client': cmd_client,
                     'result': 0,
                     'type': 0,
                     'times': 1,
                     'pdu':pdu,
                     'record_time': dt_date_time.now(),
                     'cmd_key':cmd_key,
                     'address':address.get("address",0),
                     'cmd_request': cmd_content})
                self.single_broadcast_cmd_result[cmd_key]['send_msg_num'] += 1
                '''
                senddata = self.data_encode.EncodeCompleteCmd(address.get("address"), code, pdu, value)

                self.print_debug_info(senddata, 0)
                self.patrol_sendlock.acquire()
                item['send_cmd'] = 1
                self.proclientsdict[item['unique_id']] = item
                self.patrol_sendlock.release()
                client.transport.write(senddata)
                time.sleep(2)
        else:
            cmd_content = {'address': broadcast_address, 'code': code, 'pdu': pdu, 'value': value}
            '''
            self.send_result.append(
                {'recv_client': item,
                 'cmd_client': cmd_client,
                 'result': 0,
                 'type': 1,
                 'times': 1,
                 'pdu':pdu,
                 'record_time': dt_date_time.now(),
                 'cmd_request': cmd_content})
            '''
            senddata = self.data_encode.EncodeCompleteCmd(broadcast_address, code, pdu, value)
            self.patrol_sendlock.acquire()
            item['send_cmd'] = 1
            self.proclientsdict[item['unique_id']] = item
            self.patrol_sendlock.release()
            self.print_debug_info(senddata, 0)
            client.transport.write(senddata)

    def udp_send_broadcast_cmd_request(self, cmd_type, code, pdu, value, relateid, cmd_client,cmd_key, protocol_type, is_broadcast = 1):
        # 广播相关指令的发送
        if is_broadcast == 0:
            # 单播命令先获取网络下的所有灯
            result, address_list = self.mysqlDb.get_lampinfo_groupby_network(relateid)
            if not result:
                result, address_list = self.mysqlDb.get_lampinfo_groupby_network(relateid)
            for address in address_list:

                senddata = self.data_encode.EncodeCompleteCmd(address.get("address"), code, pdu, value)
                '''
                protocol type 1 would using udp to send and get data
                '''
                udpmsg = {
                    'networkid': relateid,
                    'lampid': address.get("lampid"),
                    'protocoltype': protocol_type,
                    'address': address.get("address"),
                    'cmd_client': cmd_client,
                    'cmd_type': cmd_type,
                    'senddata': senddata
                }
                # logger.info("global_set_cmdmsg %s" % str(udpmsg))
                global_buffer.global_set_cmdmsg(udpmsg)
        else:

            if protocol_type == 1 or protocol_type == 3:
                #nbiot and lorawan not sopport the broadcast command
                return

            senddata = self.data_encode.EncodeCompleteCmd(broadcast_address, code, pdu, value)

            '''
            protocol type 1 would using udp to send and get data
            '''
            udpmsg = {
                'networkid': relateid,
                'protocoltype': protocol_type,
                'address': broadcast_address,
                'cmd_client': cmd_client,
                'cmd_type': cmd_type,
                'senddata': senddata
            }
            # logger.info("global_set_cmdmsg %s" % str(udpmsg))
            global_buffer.global_set_cmdmsg(udpmsg)


    def send_batch_update_data_new(self,cmd_client,cmd_value,id):
        cmd_index = 0

        for cmd in cmd_value:
            type = cmd['cmdtype']
            relateid = cmd['relateid']
            send_msg_num = 0
            respond_msg = 0
            if type == 0:
                result, address = self.mysqlDb.get_lamp_address_info(relateid)
                if not result:
                    result, address = self.mysqlDb.get_lamp_address_info(relateid)
                str_address = address['address'] if address.has_key("address") else ''
                network_id = address.get('networkid','')
                net_protocoltype = address.get('protocoltype', 0)
                if int(net_protocoltype) != 0:
                    '''
                    protocol type 1 would using udp to send and get data
                    '''
                    senddata = self.data_encode.EncodeQueryAllCompleteCmd(str_address, 3, 0, [])
                    udpmsg = {
                        'networkid': network_id,
                        'lampid': relateid,
                        'protocoltype': net_protocoltype,
                        'address': str_address,
                        'cmd_client': cmd_client,
                        'cmd_type': "send_batch_update_data_new",
                        'senddata': senddata
                    }

                    logger.info("global_set_cmdmsg %s" % str(udpmsg))
                    global_buffer.global_set_cmdmsg(udpmsg)
                    return True

                pdu = 0
                client_item = self.getClientByNetworkid(network_id)
                if len(client_item) == 0:
                    return False

                client = client_item.get("client", None)
                if client == None:
                    return False
                send_msg_num += 1
                cmd_index += 1
                if cmd_index == len(cmd_value):
                    respond_msg = 1
                self.patrol_sendlock.acquire()
                client_item['send_status'] = 1
                client_item['send_time'] = dt_date_time.now()
                client_item['send_cmd'] = 1
                self.proclientsdict[network_id] = client_item
                self.patrol_sendlock.release()

                self.query_result_dict[str_address] = {
                      'client_rcv': client_item,
                      'networkid': network_id,
                      'pdu': 70,
                      'type': 0,
                      'respond':respond_msg,
                      'cmd_client':cmd_client,
                      'send_num':len(cmd_value),
                      'record_time': dt_date_time.now(),
                      'times': 1}
                self.send_query_single(client, str_address, pdu, type,True)


                time.sleep(3)
            elif type == 1:
                client_item = self.getClientByNetworkid(relateid)
                if len(client_item) > 0:
                    send_msg_num += 1
                    self.send_broadcast_update_cmd(client_item,cmd_client,0)

            elif type == 2:
                net_dict_keys = self.proclientsdict.keys()
                for netdictkey in net_dict_keys:
                    client_item = self.getClientByNetworkid(netdictkey)
                    if len(client_item) == 0:
                        continue
                    if relateid == client_item['unique_prj_id']:
                        send_msg_num += 1
                        self.send_broadcast_update_cmd(client_item, cmd_client,0)

            if send_msg_num == 0:
                self.mysqlDb.update_batch_update_cmd_status(id,1)

        return True

    def send_broadcast_update_cmd(self, item, cmd_client, is_broadcast = 1):
        if is_broadcast == 0:
            # 单播命令先获取网络下的所有灯
            result, address_list = self.mysqlDb.get_lampinfo_groupby_networkEX(item["unique_id"])
            if not result:
                result, address_list = self.mysqlDb.get_lampinfo_groupby_networkEX(item["unique_id"])
            for address in address_list:
                str_address = address.get("address")
                net_protocoltype = address.get('protocoltype', 0)
                if int(net_protocoltype) != 0:
                    '''
                    protocol type 1 would using udp to send and get data
                    '''
                    senddata = self.data_encode.EncodeQueryAllCompleteCmd(str_address, 3, 0, [])
                    udpmsg = {
                        'networkid': item["unique_id"],
                        'lampid': address['lampid'],
                        'protocoltype': net_protocoltype,
                        'address': str_address,
                        'cmd_client': cmd_client,
                        'cmd_type': "send_broadcast_update_cmd",
                        'senddata': senddata
                    }
                    logger.info("global_set_cmdmsg %s" % str(udpmsg))
                    global_buffer.global_set_cmdmsg(udpmsg)
                    return True

                if len(str_address) > 0:
                    self.patrol_sendlock.acquire()
                    item['send_status'] = 1
                    item['send_cmd'] = 1
                    item['send_time'] = dt_date_time.now()
                    self.proclientsdict[item["unique_id"]] = item
                    self.patrol_sendlock.release()

                    self.query_result_dict[str_address] = {
                          'client_rcv' :item,
                          'networkid': item["unique_id"],
                          'pdu': 70,
                          'type': 0,
                          'record_time': dt_date_time.now(),
                          'times': 1}
                    self.send_query_single(item["client"], str_address, 0, 0,True)

                    time.sleep(4)
        else:

            self.send_query_single(item["client"], broadcast_address, 0, 1,True)
        return True

    def project_main_thread(self):
        logger.info("project_main_thread threadid: %d" % (getThreadId()))
        while True:
            current_time = dt_date_time.now()
            try:
                #以下两个线程是每秒钟执行一次的
                #if not self.is_decode_thread_locked:
                #    # 解析数据线程
                self.main_thread_tick += 1
                if not self.is_send_thread_locked:
                    # 发送控制指令线程
                    self.sendCmdRequestThread = threads.deferToThread(self.send_cmd_request_data_thread)
                    self.sendCmdRequestThread.addCallback(self.send_data_success)
                else:
                    pass
                    #logger.info("is_send_thread_locked is True")


                if(current_time - self.chek_result_record_time).seconds >= HEART_CHECK_INTERVAL \
                        and not self.is_result_thread_locked:
                            #重发结果监测
                    self.sendReSendThread = threads.deferToThread(self.chek_query_result_thread)
                    self.sendReSendThread.addCallback(self.send_data_success)
                    #by wender at 20160314
                    pass

                if(current_time - self.heart_beat_record_time).seconds >= HEART_CHECK_INTERVAL:
                    #重发和心跳检测
                    self.sendHeartBeatThread = threads.deferToThread(self.chek_heart_beat_thread)
                    self.sendHeartBeatThread.addCallback(self.send_data_success)
                    logger.info("decodeDataThread main_thread_tick: %d" % self.main_thread_tick)

                if (current_time - self.send_thread_record_time).seconds >= QUERY_TIME_INTERVAL \
                        and self.patrol_send_thread_locked == False:
                    #发送查询请求
                    self.sendDataThread = threads.deferToThread(self.send_query_request_data_thread)
                    self.sendDataThread.addCallback(self.send_data_success)

                #发送查询请求
                #if not self.is_patrol_thread_locked and not self.send_patrol_cmd_queue.empty() :
                    #self.sendDataThread = threads.deferToThread(self.send_query_request_data)
                    #self.sendDataThread.addCallback(self.send_data_success)

            except Exception,e:
                logger.error("project_main_thread error %s"%str(e))
                pass
            time.sleep(1)
        return {'result': True,
                'message':"project_main_thread:main thread over"}

    def send_query_request_data_thread(self):
        self.patrol_send_thread_locked = True
        try:
            self.send_thread_record_time = dt_date_time.now()
            if self.patrol_send_thread_count < 20:
                result, rules = self.mysqlDb.get_patrol_rules()
                if not result:
                    self.patrol_send_thread_locked = False
                    return {'result': False,
                            'message': "send_query_request_data_thread: sendDataThread over new record time %s" % str(
                                self.send_thread_record_time)}
                if len(rules) > 0:

                    rule_list = []
                    logger.info("all query patrol_roles count :%s" % len(rules))
                    post_count = len(rules)/15
                    if post_count < 200:
                        post_count = 200
                    for i in range(0, len(rules), post_count):
                        rule_list.append(rules[i:i + post_count])

                    for i in range(0, len(rule_list)):
                        if len(rule_list[i]) > 0:
                            threads.deferToThread(self.send_query_request_data, rule_list[i])
                            logger.info("get query patrol_roles count :%s"%len(rule_list[i]))
            self.patrol_send_thread_locked = False
        except Exception, e:
            logger.errr(traceback.format_exc())
            self.patrol_send_thread_locked = False
            return {'result': False,
                    'message': "send_query_request_data_thread: sendDataThread over new record time %s" % str(
                        self.send_thread_record_time)}
        self.patrol_send_thread_locked = False
        return {'result': True,
                'message': "send_query_request_data_thread: sendDataThread over new record time %s" % str(
                    self.send_thread_record_time)}

    def send_query_request_data(self, patrol_list):
        try:
            self.patrol_sendlock.acquire()
            self.patrol_send_thread_count += 1
            self.patrol_sendlock.release()
            send_count = 0


            rules = [cmd for cmd in patrol_list]
            logger.info("send_query_request_data threadid: %d, threadcount %ds, patrol_roles count :%s" % (
                                                    getThreadId(), self.patrol_send_thread_count, len(rules)))

            #logger.error("patrol_roles:%s"%str(rules))
            if len(rules) > 0:
                self.read_lamp_config()
            logger.info("11111rules start search")

            while(len(rules) > 0):

                time.sleep(0.005)
                current_time = dt_date_time.now()
                # if send rules times is mose than 55 second, would set it to next time to send

                net_dict_keys = self.proclientsdict.keys()
                for netdictkey in net_dict_keys:
                    time.sleep(0.005)
                    client_item = self.getClientByNetworkid(netdictkey)
                    if len(client_item) == 0:
                        continue
                    last_time = client_item.get('send_time', None)
                    if last_time == None:
                        continue
                    if client_item['send_cmd'] == 1:
                        continue

                    if client_item['send_status'] == 1 and (current_time - last_time).seconds < 15:
                        continue
                    else:
                        client_item['send_status'] = 0

                    for rule in rules:
                        time.sleep(0.005)
                        type = rule['cmdtype']
                        relateid = rule['relateid']
                        address = rule['address']
                        network_id = address.get('networkid', '')
                        str_address = address['address'] if address.has_key("address") else ''
                        if network_id in net_dict_keys:
                            pass
                        else:
                            #logger.info("rule not in net dict, addr:%s"%address)
                            rules.remove(rule)
                            continue

                        if network_id != netdictkey:
                            continue
                        #logger.info("relateid :%s"%str(rule['relateid']))
                        if type == 0:

                            client = client_item["client"]
                            self.send_query_single(client, str_address, 0, type, True)
                            send_count += 1
                            logger.info("threadid: %d, send_count %ds" % (getThreadId(), send_count))
                            rules.remove(rule)
                            self.patrol_sendlock.acquire()
                            client_item['send_status'] = 1
                            client_item['send_time'] = dt_date_time.now()
                            self.proclientsdict[netdictkey] = client_item
                            self.patrol_sendlock.release()
                            """
                            self.query_result_dict[str_address] = {
                                  'networkid': network_id,
                                  'pdu': 70,
                                  'type': 0,
                                  'record_time': dt_date_time.now(),
                                  'times': 1}
                            """
                            break
            self.patrol_sendlock.acquire()
            self.patrol_send_thread_count -= 1
            self.patrol_sendlock.release()
            logger.info("11111rules end search")

        except Exception, e:
            logger.error("send_query_request_data %s" % traceback.format_exc())
            return {"result":False,"msg":u"发送出错 错误信息：{error}".format(error = str(e))}

        return {"result":True,"msg":"send patral cmd finished"}

    def decodeDataThread(self):
        logger.info("decodeDataThread threadid: %d" % (getThreadId()))
        while(True):
            current_time = dt_date_time.now()
            if (current_time - self.decode_thread_record_time).seconds < 5:
                time.sleep(1)
                continue

            logger.info("decodeDataThread decode_thread_record_tick: %d" % (self.decode_thread_record_tick))
            #self.is_decode_thread_locked = True
            self.decode_thread_record_time = dt_date_time.now()
            if len(self.msg_buffer) <= 0:
                continue

            self.decode_thread_record_tick += 1
            decode_buffer = []
            decode_buffer = [msg for msg in self.msg_buffer]

            del self.msg_buffer[:]
            for item in decode_buffer:
                current_time = time.time()*1000;
                client = item["client"]
                ipAddr = client.getIPaddr()

                try:
                    packet_str = item['buffer'].lower()
                    if packet_str.startswith("register"):
                        #register
                        logger.info( item['buffer'].encode("utf-8"))
                        logger.info( "Connection:%s"% client.getId())
                        register_info = item['buffer'].encode("utf-8").split("-")
                        company = register_info[1]
                        result, network_info = self.mysqlDb.get_network_info(company, register_info[2], register_info[3])
                        conn_times = 0
                        while not result and conn_times < 3:
                            #no result connect 3 times
                            conn_times += 1
                            result, network_info = self.mysqlDb.get_network_info(company, register_info[2], register_info[3])
                        if not network_info['id']:
                            logger.error("incorrect network id company=%s, projectid=%s, networkid =%s." %(company, register_info[2], register_info[3]))
                            client.transport.write("err")
                            client.transport.loseConnection()
                            continue

                        client.transport.write("ok")
                        networkid = network_info['id']
                        if networkid not in self.proclientsdict:

                            newrelation = {
                                    "client": client,
                                    "user_name": register_info[1],
                                    "prj_id": register_info[2],
                                    "network_id": register_info[3],
                                    "unique_id": network_info['id'],
                                    "unique_prj_id": network_info['prj_id'],
                                    "address": register_info[4] if len(register_info) > 4 else '',
                                    'no_res': 0,
                                    'status': 1,
                                    'send_status': 0,
                                    'send_cmd': 0,
                                    'send_time': dt_date_time.now(),
                                    'heart_period': network_info['heart_period'],
                                    'last_time': dt_date_time.now()
                                    }
                            ip_info = ipAddr.split(":")
                            self.mysqlDb.reset_network_status([{'network_id': network_info['id'], 'status': 1, 'ip':ip_info[0], 'port':ip_info[1]}])
                            self.addProClient(newrelation)
                            self.netlistdict[ipAddr] = network_info['id']
                            logger.info("new relation networkid is %s" % network_info['id'])
                        else:
                            client_item = self.proclientsdict[networkid]
                            if 'client' in client_item:
                                old_ipaddr = client_item['client'].getIPaddr()
                                if old_ipaddr in self.netlistdict:
                                    del self.netlistdict[old_ipaddr]
                                client_item['client'] = client
                                self.netlistdict[ipAddr] = networkid

                    elif packet_str.startswith("heartbeat") or packet_str.startswith("heatbeat"):  # Todo heart-beat
                        time.sleep(0.001)
                        client_item, network_id = self.getClientByIPaddr(ipAddr)
                        if client_item != None:
                            self.patrol_sendlock.acquire()
                            client_item['status'] = 1
                            client_item['no_res'] = 0
                            client_item['last_time'] = dt_date_time.now()
                            self.proclientsdict[network_id] = client_item
                            self.patrol_sendlock.release()
                            #logger.info('heartbeat:name %s-%s-%s' % (client_item['user_name'], client_item['prj_id'], client_item['network_id']))
                        else:
                            ip_info = ipAddr.split(":")
                            logger.info('heartbeat: (ip:%s:%s)not register' % (ip_info[0], ip_info[1]))
                    elif packet_str.startswith("userheartbeat"):  # Todo heart-beat
                        logger.info('heartbeat:%s' % item['buffer'])
                        for pushItem in self.pushuserlists:
                            if pushItem['client'] == client:
                                pushItem['last_time'] = dt_date_time.now()
                                break
                    elif packet_str.startswith("user"):
                        logger.info('user:%s' % item['buffer'])
                        user_data = item['buffer'].encode("utf-8").split(":")
                        user_info = self.mysqlDb.get_user_info(user_data[1])
                        if len(user_info) > 0:
                            user_dist = user_info[0]
                            if user_dist['role'] == 3:
                                project_list = user_dist['zone'].split(",")
                                for proj_id in project_list:
                                    user_push  = {
                                        "client": client,
                                        "user_name": user_data[1],
                                        "prj_id": proj_id,
                                        'last_time':dt_date_time.now(),
                                        }
                                    self.pushuserlists.append(user_push)
                            elif user_dist['role'] == 2:
                                project_id_lists = self.mysqlDb.get_project_id_lists(user_dist['companyid'])
                                if len(project_id_lists) > 0:
                                    for proj_id in project_id_lists:
                                        logger.info('proj_id:%s' % str(proj_id))
                                        user_push  = {
                                            "client": client,
                                            "user_name": user_data[1],
                                            "prj_id": proj_id['id'],
                                            'last_time':dt_date_time.now(),
                                        }
                                        self.pushuserlists.append(user_push)
                            elif user_dist['role'] == 1:
                                user_push  = {
                                    "client": client,
                                    "user_name": user_data[1],
                                    "prj_id": 0,
                                    'last_time':dt_date_time.now(),
                                }
                                self.pushuserlists.append(user_push)
                            client.transport.write("ok,conect")
                            #logger.info(" self.pushuserlists %s"%str(self.pushuserlists))
                        client.transport.write("connect error")
                    else:

                        cur_client, network_id = self.getClientByIPaddr(ipAddr)
                        if cur_client == None:
                            continue
                        self.patrol_sendlock.acquire()
                        cur_client['send_status'] = 0
                        self.proclientsdict[network_id] = cur_client
                        self.patrol_sendlock.release()

                        res, error_msg, flag, pdu, macaddr = self.data_decode.DecodeCompleteMsg(item['buffer'])
                        if res:
                            data_MAC = '%08x' % macaddr
                            logger.info(" data_MAC %s" % str(data_MAC))

                            if flag != 3:
                                for result_s in self.send_result:
                                    client_recv = result_s['recv_client']

                                    if client == client_recv['client'] and result_s['result'] == 0 and result_s.get("pdu") == pdu:
                                        self.storageTag.storage_update_lamp_devstatus(result_s['relateid'], 0)
                                        if 'cmd_key' in result_s:
                                            #logger.info("pdu:%s"% str(result_s.get("pdu")))
                                            if result_s.get("address", '') == data_MAC:
                                                result_s['result'] = 1
                                                break   #仅仅找到一条记录就行了
                                            else:
                                                pass
                                        elif result_s.get("address", '') == data_MAC:
                                            if "cmd_key" not in result_s:
                                                #logger.info("pdu:%s"% str(result_s.get("pdu")))
                                                if result_s.get("pdu") == 0x300:
                                                    self.mysqlDb.update_lampstatus(result_s['relateid'], self.data_decode.lampstatus)
                                                if result_s.get("pdu") == 0x304:
                                                    self.mysqlDb.update_lighteness(result_s['relateid'], self.data_decode.lighteness)
                                                if result_s.get("pdu") == 0x305:
                                                    self.mysqlDb.update_electric_supply_status(result_s['relateid'], self.data_decode.electric_supply_status)

                                                result_s['cmd_client'].transport.write(json.dumps({'result': True, 'msg': "send cmd success!"}) + '\n')
                                            result_s['result'] = 1
                                            break   #仅仅找到一条记录就行了

                            else:
                                if self.query_result_dict.has_key(data_MAC):
                                    #logger.info("query_result_dict %s" % str(data_MAC))
                                    query_item = self.query_result_dict[data_MAC]
                                    if query_item.has_key('cmd_client'):
                                        if query_item['respond'] == 1:
                                            return_value = json.dumps({'result': True,
                                                'msg': u'实时更新指令发送完成',
                                                'total_num':query_item['send_num'],
                                                'succeed_num':query_item['send_num']}) + '\n'
                                            query_item['cmd_client'].transport.write(return_value)
                                    del self.query_result_dict[data_MAC]

                                if pdu == 0x328 or pdu == 0x400:
                                    for result_s in self.send_result:
                                        client_recv = result_s['recv_client']
                                        if client == client_recv['client'] and result_s['result'] == 0 and result_s.get("pdu") == pdu:
                                            self.storageTag.storage_update_lamp_devstatus(result_s['relateid'], 0)
                                            if pdu == 0x328:
                                                self.mysqlDb.get_battery_setting_info(result_s['relateid'], self.data_decode.BatterySettingInfo)
                                            elif pdu == 0x400:
                                                self.mysqlDb.get_load_setting_info(result_s['relateid'], self.data_decode.LoadParamSettingInfo)
                                            result_s['cmd_client'].transport.write(json.dumps({'result': True, 'msg': "send cmd success!"}) + '\n')
                                            result_s['result'] = 1
                                            break
                                else:
                                    data = self.data_decode.all_data
                                    alarm_projectid = 0
                                    if self.lamp_config_info_dict.has_key(data_MAC):
                                        config = self.lamp_config_info_dict[data_MAC]
                                        if(str(cur_client["prj_id"]) == config["projectid"] and str(cur_client["network_id"]) == config["networkid"]):
                                            logger.info("lamp_id %s" % config['id'])
                                            lampid = config["id"]
                                            self.storageTag.storage_update_lamp_devstatus(lampid, 0)
                                            result = {"lamp_id": lampid,
                                                    "projectid": config["projectid"],
                                                    "networkid": config["networkid"]}
                                            #logger.info("result %s"%result)
                                            result.update(data)
                                            self.save_db_buffer_dict[lampid] = result

                                    #logger.info(" alarm_projectid %s"%alarm_projectid)
                                    #logger.info(" alarm_info %s"%str(self.data_decode.all_data['AlarmInfo']))
                                    if alarm_projectid > 0:
                                        alarm_info = self.data_decode.all_data['AlarmInfo']
                                        if alarm_info['alarm_type'] > 0:
                                            for push_item in self.pushuserlists:
                                                if push_item['prj_id'] == 0 :
                                                    push_item['client'].transport.write(json.dumps(alarm_info) + '\n')
                                                elif alarm_projectid == push_item['prj_id']:
                                                    push_item['client'].transport.write(json.dumps(alarm_info) + '\n')
                                    for result_s in self.send_result:
                                        client_recv = result_s['recv_client']
                                        if (client == client_recv['client'] and result_s['result'] == 0) and result_s.get("pdu") == pdu and (result_s['cmd_request'].get("code") == 0x0f&flag):
                                            #失败的可以继续发送，直到成功
                                            result_s['cmd_client'].transport.write(json.dumps({'result':False,'msg':"unknown error"})+'\n')
                                            result_s['result'] = 1
                                            logger.error("send cmd error info to %s", str(result_s['cmd_client'].getId()))
                                            break
                                #logger.info(time.time()*1000-current_time)
                        else:

                            self.print_string2hex(item['buffer'], network_id)
                            for result_s in self.send_result:
                                client_recv = result_s['recv_client']
                                if client == client_recv['client'] and result_s['result'] == 0:
                                    self.storageTag.storage_update_lamp_devstatus(result_s['relateid'], 3)
                                    result_s['result'] = 0
                                    if "cmd_key" not in result_s:
                                        result_s['cmd_client'].transport.write(json.dumps({'result':False,'msg':error_msg})+'\n')
                                    logger.error("send cmd error info to %s"%str(result_s['cmd_client'].getId()))
                                    logger.error("send cmd error info to %s"%error_msg)
                                    break

                except Exception,e:
                    logger.error("%s" % traceback.format_exc())
                    continue
            del decode_buffer[:]
            #self.is_decode_thread_locked = False
            #return {'result':True,
            #        'message':"decodeDataThread:decodeDataThread over is ok record time %s"%self.decode_thread_record_time}

    def decodeData(self, client, buffer):
        if buffer.find("cmd_type") != -1 :
            self.cmd_buffer.append({'client':client,'buffer':buffer})
        else:
            #if buffer.isalpha():
                #logger.info("recevice: %s" % buffer)
            #self.print_debug_info(buffer, 1)
            self.msg_buffer.append({'client':client,
                'buffer':buffer})
            self.update_client_time(client)
        return 0

    def update_client_time(self, client):
        try:
            ipAddr = client.getIPaddr()
            client_item, network_id = self.getClientByIPaddr(ipAddr)
            if client_item != None:
                self.patrol_sendlock.acquire()
                client_item['last_time'] = dt_date_time.now()
                self.proclientsdict[network_id] = client_item
                self.patrol_sendlock.release()

        except Exception, e:
            logger.error("update_client_time: %s" % str(e))

